// token使用
import {
	getToken
} from "./w_token.js";
// #ifdef MP-WEIXIN
// 实时日志
// const log = require("./wx_log.js");
import log from './wx_log.js';
// #endif
// 默认配置
let defaultConfig = {
	// 请求配置
	baseURL: '', // 请求的 baseURL（域名地址）
	url: '', // 接口地址
	data: {}, // 请求的参数
	method: 'POST', // HTTP 请求方法
	header: {
		'content-type': 'application/json' // 默认值
	}, // 设置请求的 header，header 中不能设置 Referer。content-type 默认为 application/json
	timeout: 10000, // 超时时间，默认10秒，单位为毫秒
	// 其他配置
	debug: true, // 是否开启打印调试
	alert_time_duration: 1000, // 弹框显示时间
	alert_timeout: true, // 请求超时弹框
	alert_timeout_text: '网络繁忙，请稍后再试！', // 请求超时弹框提示内容
	alert_success: false, // 请求成功弹框
	alert_success_text: '', // 请求成功弹框提示内容
	alert_error: true, // 请求失败弹框
	alert_error_text: '', // 请求失败弹框提示内容
}
// 请求方法
const wRequest = function (params) {
	// 引用实例
	const app = getApp();
	defaultConfig.baseURL = app.globalData.wReqUrl;  // 请求的 baseURL（域名地址）

	return new Promise((resolve, reject) => {
		(params && Object.prototype.toString.call(params) === '[object Object]') || (
			params = {}); // 判断参数是否是对象
		let config = {
			...defaultConfig,
			...params,
		};
		// 开发者服务器接口地址
		config.url = `${config.baseURL}${config.path}`;
		// 接口调用成功的回调函数
		if (Object.prototype.toString.call(config.success) != '[object Function]') {
			config.success = (res) => {
				if (res.statusCode == 200) {
					// 返回值
					let resData = res.data;
					// 调试
					if (config.debug) {
						console.log('接口:', config.path, '请求结果:', resData);
					}
					// 服务器返回的code编码，例:200-正确
					if (resData.code == 200) {
						// #ifdef MP-WEIXIN
						// 实时日志
						log.info(
							`接口请求——接口:${config.path},参数:${JSON.stringify(config.data)},结果:${JSON.stringify(resData)}`
						);
						// #endif
						if (config.alert_success) {
							uni.showToast({
								title: `${config.alert_success_text ? config.alert_success_text : resData.msg}`,
								icon: 'none',
								mask: true,
								duration: config.alert_time_duration,
							})
							resolve(resData);
						} else {
							resolve(resData);
						}
					} else {
						// #ifdef MP-WEIXIN
						// 实时日志
						log.error(
							`接口请求——接口:${config.path},参数:${JSON.stringify(config.data)},结果:${JSON.stringify(resData)}`
						);
						// #endif
						if (config.alert_error) {
							uni.showToast({
								title: `${config.alert_error_text ? config.alert_error_text : resData.msg}`,
								icon: 'none',
								mask: true,
								duration: config.alert_time_duration,
							})
							reject(resData);
						} else {
							reject(resData);
						}
					}
				} else {
					// #ifdef MP-WEIXIN
					// 实时日志
					log.error(
						`接口请求——接口:${config.path},参数:${JSON.stringify(config.data)},结果:${JSON.stringify(res)}`
					);
					// #endif
					// 调试
					console.error('接口:', config.path, '错误:', res);
					reject(res);
				}
			};
		}
		// 接口调用失败的回调函数
		if (Object.prototype.toString.call(config.fail) != '[object Function]') {
			config.fail = (err) => {
				// #ifdef MP-WEIXIN
				// 实时日志
				log.error(
					`接口请求——接口:${config.path},参数:${JSON.stringify(config.data)},结果:${JSON.stringify(err)}`
				);
				// #endif
				// 调试
				console.log('接口:', config.path, '错误:', err);
				if (config.alert_timeout && err.errMsg == "request:fail timeout") {
					uni.showToast({
						title: config.alert_timeout_text,
						icon: 'none',
						mask: true,
					})
				}
				reject(err);
			};
		}
		// 接口调用结束的回调函数（调用成功、失败都会执行）
		if (Object.prototype.toString.call(config.complete) != '[object Function]') {
			config.complete = (result) => { };
		}
		// 是否需要设置 token
		const isToken = (config.header || {}).isToken === false;
		// 添加 token
		if (getToken() && !isToken) {
			config.header['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
		}
		// 是否需要防止数据重复提交
		const isRepeatSubmit = (config.header || {}).repeatSubmit === false;
		const isRepeatSubmit_time = (config.header || {}).repeatSubmitTime || 1000;
		// 添加请求参数(防止数据重复提交)(简易版-单线程网络请求)
		if (!isRepeatSubmit) {
			const requestObj = {
				url: config.url,
				data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
				time: new Date().getTime()
			}
			const storageObj = uni.getStorageSync('storageObj')
			if (storageObj === undefined || storageObj === null || storageObj === '') {
				uni.setStorageSync('storageObj', JSON.stringify(requestObj)); // 转换为JSON字符串缓存
			} else {
				storageObj = JSON.parse(storageObj); // 转换为JSON对象
				const s_url = storageObj.url; // 请求地址
				const s_data = storageObj.data; // 请求数据
				const s_time = storageObj.time; // 请求时间
				const interval = isRepeatSubmit_time; // 间隔时间(ms)，小于此时间视为重复提交
				if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url ===
					requestObj.url) {
					const message = '数据正在处理，请勿重复提交';
					console.warn(`[${s_url}]: ` + message)
					uni.showToast({
						title: message,
						icon: 'none',
						mask: true,
					})
					reject(message);
				} else {
					uni.setStorageSync('storageObj', JSON.stringify(requestObj)); // 转换为JSON字符串缓存
				}
			}
		}
		// 调试
		if (config.debug) {
			console.log('请求配置文件：', config);
			console.log('接口:', config.path, '请求参数:', config.data);
		}
		// 发起 HTTPS 网络请求
		uni.request(config);
	});
}
// get
const wGet = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'GET';
	return wRequest(params);
}
// post
const wPost = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'POST';
	return wRequest(params);
}
// options
const wOptions = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'OPTIONS';
	return wRequest(params);
}
// head
const wHead = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'HEAD';
	return wRequest(params);
}
// put
const wPut = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'PUT';
	return wRequest(params);
}
// delete
const wDelete = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'DELETE';
	return wRequest(params);
}
// trace
const wTrace = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'TRACE';
	return wRequest(params);
}
// connect
const wConnect = function (url, params) {
	(params && Object.prototype.toString.call(params) === '[object Object]') || (params = {}); // 判断参数是否是对象
	params.path = url;
	params.method = 'CONNECT';
	return wRequest(params);
}

export default {
	request: wRequest,
	get: wGet,
	post: wPost,
	options: wOptions,
	head: wHead,
	put: wPut,
	delete: wDelete,
	trace: wTrace,
	connect: wConnect,
}
